package ferp.android.activities;

import android.app.Activity;
import android.os.Bundle;
import android.text.Spanned;
import android.view.Display;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import ferp.android.GUI;
import ferp.android.R;
import ferp.android.activities.preferences.Preferences;
import ferp.android.managers.ProfileManager;
import ferp.core.player.Profile;

import java.util.HashSet;
import java.util.Set;

/**
 * User: olegs
 * Date: 7/24/13 4:06 PM
 */
public class Statistics extends Activity
{
  @Override
  public void onBackPressed()
  {
    // propagate the event to parent tab host activity
    getParent().onBackPressed();
  }

  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    Profile profile = ProfileManager.instance(this).getCurrentProfile();

    GUI.setOrientation(this, profile);

    super.onCreate(savedInstanceState);

    Preferences.setLocale(this, profile);

    setContentView(R.layout.statistics);

    scroll = (ScrollView)findViewById(R.id.statistics_scroll);

    // on 7" tablet emulator returned height still equals to width here, when device is turned in landscape, but the profile is shown as portrait
    Display d = getWindowManager().getDefaultDisplay();
    int h = d.getHeight();
    int w = d.getWidth();

    screenHeight = profile.isLandscape() ? Math.min(h, w) : Math.max(h, w);

    setupElements();
  }

  private void setupElements()
  {
    Profile p = ProfileManager.instance(this).getCurrentProfile();

    ferp.core.game.Statistics total = p.getStatistics();
    ferp.core.game.Statistics current = p.game() == null ? null : p.game().statistics;

    setupTripleElement("statistics_score_total", R.string.statistics_score_total, R.string.statistics_note_score_total, total.score, current == null ? null : current.score, true);
    setupSingleElement("statistics_games_played", R.string.statistics_games_played, R.string.statistics_note_games_played, total.numOfGames, total.numOfGames == total.games.played ? null : total.games.played);
    setupSingleElement("statistics_games_pool", R.string.statistics_games_pool, R.string.statistics_note_games_pool, total.totalPool, total.totalPool == total.games.pool ? null : total.games.pool);
    setupSingleElement("statistics_games_deleted", R.string.statistics_games_deleted, R.string.statistics_note_games_deleted, total.games.deleted, null);
    setupTripleElement("statistics_score_average", R.string.statistics_score_average, R.string.statistics_note_score_average, total.getAverageScore(), current == null ? null : current.getAverageScore(), true);
    setupSingleElement("statistics_deals", R.string.statistics_deals, R.string.statistics_note_deals, total.sets.deals, current == null ? null : current.sets.deals);
    setupSingleElement("statistics_games_tricking", R.string.statistics_games_tricking, R.string.statistics_note_games_tricking, total.getNumberOfTrickingSets(), current == null ? null : current.getNumberOfTrickingSets());

    for (int i = 6; i < 11; ++i)
    {
      String id = "statistics_games_tricking_" + i;
      int resTitle = getResources().getIdentifier(id, "string", getPackageName());
      int resNote = getResources().getIdentifier("statistics_note_games_tricking_" + i, "string", getPackageName());

      setupTripleElement(id, resTitle, resNote, total.getTrickingSetResult(i), current == null ? null : current.getTrickingSetResult(i));
    }

    setupTripleElement("statistics_games_without3", R.string.statistics_games_without3, R.string.statistics_note_games_without3, total.without3, current == null ? null : current.without3, false);
    setupTripleElement("statistics_games_misere", R.string.statistics_games_misere, R.string.statistics_note_games_misere, total.getMisereSetResult(), current == null ? null : current.getMisereSetResult());
    setupSingleElement("statistics_games_passing", R.string.statistics_games_passing, R.string.statistics_note_games_passing, total.sets.passing, current == null ? null : current.sets.passing);
    setupTripleElement("statistics_average_tricks_when_pass", R.string.statistics_average_tricks_when_pass, R.string.statistics_note_average_tricks_when_pass, total.getAveragePassingTricks(), current == null ? null : current.getAveragePassingTricks());
    setupTripleElement("statistics_games_whisting", R.string.statistics_games_whisting, R.string.statistics_note_games_whisting, total.getWhistedSets(), current == null ? null : current.getWhistedSets());
    setupTripleElement("statistics_ratio_whists_to_passes", R.string.statistics_ratio_whists_to_passes, R.string.statistics_note_ratio_whists_to_passes, total.getRatioWhistsToPasses(), current == null ? null : current.getRatioWhistsToPasses());
  }

  private void setupSingleElement(String element, int resTitle, int resNote, long total, Long current)
  {
    setupSingleElement(element, resTitle, resNote, String.valueOf(total), current == null ? null : current.toString());
  }

  private void setupSingleElement(String element, int resTitle, int resNote, String total, String current)
  {
    LinearLayout l = resolveElement(element, resTitle, resNote);

    setText(l, R.id.statistics_value_total, total);
    l.findViewById(R.id.statistics_value_delimiter).setVisibility(current == null ? View.GONE : View.VISIBLE);
    setText(l, R.id.statistics_value_current, current);
  }

  private void setupTripleElement(String element, int resTitle, int resNote, long[] total, long[] current, boolean score)
  {
    setupTripleElement(element, resTitle, resNote, R.id.statistics_item_total, R.id.statistics_value_delimiter, R.id.statistics_item_current,
                       score ? Format.score(total, 0) : Format.number(total, 0), score ? Format.score(current, 0) : Format.number(current, 0),
                       score ? Format.score(total, 1) : Format.number(total, 1), score ? Format.score(current, 1) : Format.number(current, 1),
                       score ? Format.score(total, 2) : Format.number(total, 2), score ? Format.score(current, 2) : Format.number(current, 2));
  }

  private void setupTripleElement(String element, int resTitle, int resNote, double[] total, double[] current)
  {
    setupTripleElement(element, resTitle, resNote, R.id.statistics_item_total, R.id.statistics_value_delimiter, R.id.statistics_item_current,
                       Format.number(total, 0), Format.number(current, 0),
                       Format.number(total, 1), Format.number(current, 1),
                       Format.number(total, 2), Format.number(current, 2));
  }

  private void setupTripleElement(String element, int resTitle, int resNote, ferp.core.game.Statistics.Percentage[] total, ferp.core.game.Statistics.Percentage[] current)
  {
    setupTripleElement(element, resTitle, resNote, R.id.statistics_item_total_0, R.id.statistics_item_delimiter_0, R.id.statistics_item_current_0,
                       Format.percentageTotal(total, 0), Format.percentageTotal(current, 0),
                       Format.percentageTotal(total, 1), Format.percentageTotal(current, 1),
                       Format.percentageTotal(total, 2), Format.percentageTotal(current, 2));

    setupTripleElement(element, resTitle, resNote, R.id.statistics_item_total_1, R.id.statistics_item_delimiter_1, R.id.statistics_item_current_1,
                       Format.percentagePos(total, 0), Format.percentagePos(current, 0),
                       Format.percentagePos(total, 1), Format.percentagePos(current, 1),
                       Format.percentagePos(total, 2), Format.percentagePos(current, 2));
  }

  private void setupTripleElement(String element, int resTitle, int resNote, ferp.core.game.Statistics.Ratio[] total, ferp.core.game.Statistics.Ratio[] current)
  {
    setupTripleElement(element, resTitle, resNote, R.id.statistics_item_total, R.id.statistics_value_delimiter, R.id.statistics_item_current,
                       Format.ratio(total, 0), Format.ratio(current, 0),
                       Format.ratio(total, 1), Format.ratio(current, 1),
                       Format.ratio(total, 2), Format.ratio(current, 2));
  }

  private void setupTripleElement(String element, int resTitle, int resNote, int resTotal, int resDelimiter, int resCurrent,
                                  CharSequence humanTotal, CharSequence humanCurrent,
                                  CharSequence leftTotal, CharSequence leftCurrent,
                                  CharSequence rightTotal, CharSequence rightCurrent)
  {
    LinearLayout l = resolveElement(element, resTitle, resNote);

    setupTripleElement(l, R.id.statistics_human, resTotal, humanTotal);
    setupTripleElement(l, R.id.statistics_human, resCurrent, humanCurrent);
    l.findViewById(R.id.statistics_human).findViewById(resDelimiter).setVisibility(humanCurrent == null ? View.GONE : View.VISIBLE);

    setupTripleElement(l, R.id.statistics_android_left, resTotal, leftTotal);
    setupTripleElement(l, R.id.statistics_android_left, resCurrent, leftCurrent);
    l.findViewById(R.id.statistics_android_left).findViewById(resDelimiter).setVisibility(humanCurrent == null ? View.GONE : View.VISIBLE);

    setupTripleElement(l, R.id.statistics_android_right, resTotal, rightTotal);
    setupTripleElement(l, R.id.statistics_android_right, resCurrent, rightCurrent);
    l.findViewById(R.id.statistics_android_right).findViewById(resDelimiter).setVisibility(humanCurrent == null ? View.GONE : View.VISIBLE);
  }

  private LinearLayout resolveElement(String name, int resTitle, int resNote)
  {
    LinearLayout l = (LinearLayout)findViewById(getResources().getIdentifier(name, "id", getPackageName()));
    TextView title = (TextView)l.findViewById(R.id.statistics_title);
    TextView note = (TextView)l.findViewById(R.id.statistics_note);

    title.setTypeface(GUI.Font.BOLD);
    title.setText(resTitle);

    note.setTypeface(GUI.Font.NORMAL);
    note.setTextColor(0xBBFFFFFF);
    note.setText(resNote);

    l.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        View note = view.findViewById(R.id.statistics_element_note);

        if (expanded.contains(view))
          collapse(view, note);
        else
          expand(view, note);
      }
    });

    return l;
  }

  private void collapse(View element, View note)
  {
    note.setVisibility(View.GONE);
    expanded.remove(element);

    TextView tv = (TextView)element.findViewById(R.id.statistics_button_folding);
    tv.setText(Folding.COLLAPSED);
  }

  private void expand(final View element, View note)
  {
    element.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
    {
      @Override
      public void onGlobalLayout()
      {
        GUI.removeGlobalOnLayoutListener(element, this);

        int[] location = new int[2];
        element.getLocationOnScreen(location);

        //Log.log.debug(Log.TAG, "onLayoutChanged: " + location[0] + ", " + (location[0] + element.getWidth()) + ", " + location[1] + ", " + (location[1] + element.getHeight()));

        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)element.getLayoutParams();
        int bottom = location[1] + element.getHeight() + lp.topMargin + lp.bottomMargin;

        //Log.log.debug(Log.TAG, "onLayoutChanged: screen height = " + screenHeight + ", bottom = " + bottom);

        if (bottom > screenHeight)
          scroll.scrollBy(0, bottom - screenHeight);
      }
    });

    note.setVisibility(View.VISIBLE);
    expanded.add(element);

    TextView tv = (TextView)element.findViewById(R.id.statistics_button_folding);
    tv.setText(Folding.EXPANDED);
  }

  private void setText(LinearLayout player, int id, CharSequence text)
  {
    TextView tv = (TextView)player.findViewById(id);

    if (text == null)
      tv.setVisibility(View.GONE);
    else
    {
      tv.setTypeface(GUI.Font.NORMAL);
      tv.setText(text);
    }
  }

  private void setupTripleElement(LinearLayout l, int item, int id, CharSequence value)
  {
    LinearLayout player = (LinearLayout)l.findViewById(item);

    if (item == R.id.statistics_human)
    {
      player.findViewById(R.id.statistics_player_icon_human).setVisibility(View.VISIBLE);
      player.findViewById(R.id.statistics_player_icon_android).setVisibility(View.GONE);
    }

    setText(player, id, value);
  }

  private final static class Folding
  {
    private static final String COLLAPSED = "▼";
    private static final String EXPANDED  = "▲";
  }

  private final static class Format
  {
    private static Spanned score(long[] values, int i)
    {
      if (values == null)
        return null;

      String color;
      if (values[i] == 0)
        color = "white";
      else
        color = values[i] > 0 ? "#00FF00" : "red";

      return GUI.getColoredText(color, values[i]);
    }

    private static String number(long[] values, int i)
    {
      return values == null ? null : String.valueOf(values[i]);
    }

    private static String number(double[] values, int i)
    {
      return values == null ? null : ferp.core.game.Statistics.nf.format(values[i]);
    }

    private static String percentageTotal(ferp.core.game.Statistics.Percentage[] values, int i)
    {
      return values == null ? null : String.valueOf(values[i].total);
    }

    private static String percentagePos(ferp.core.game.Statistics.Percentage[] values, int i)
    {
      return values == null ? null : values[i].pos();
    }

    private static String ratio(ferp.core.game.Statistics.Ratio[] values, int i)
    {
      return values == null ? null : values[i].toString();
    }
  }

  private ScrollView scroll;
  private int screenHeight;

  private Set<View> expanded = new HashSet<View>();
}
